;(function($) {
    $.fn.extend({
        caption: function(html, options) {  
            return this.each(function() {
                var caption = $.data(this,'caption');
                if(html == ":remove"){
                    if(caption){
                        caption.remove();
                        $.removeData(this,'caption');
                    }
                }
                else if(!caption){
                    caption = new $.Caption(this,html, options);
                    $.data(this,'caption',caption);
                }
                else{
                    caption.setOptions(options).setHTML(html);
                }    
            });
        }
    });

    $.Caption = function(input,html, opt) {
        var options = $.extend({},$.Caption.defaults) ;
        var self = this;
        var $input = $(input);
        var $caption = $('<div/>').hide().css({position: 'absolute'}).appendTo(document.body);
        var $bindElements  = $input; 
        this.statusShow = false;  
        this.cMouseleave = function(event){
            self.hide();      
        }
        this.cMouseenter = function(event){ 
            self.show();      
        }
        this.setOptions = function (opt){
            options = $.extend(options,opt);         
            return this;            
        };
        this.setHTML = function(html){                                     
            $caption.html(html).hide();
             $('<div />').addClass('cv').appendTo($caption);
             if(self.statusShow){
                self.statusShow = false;
                 self.show();
             } 
             return this;              
        };
        this.show = function (){
             if(self.statusShow)
                return this;
            var align = options.align;
            var captionWidth = options.width=='auto' ? $input.width() : options.width; 
            $caption.removeClass().addClass('caption').addClass(options.color).addClass('c'+align).css({width:captionWidth});
            var offset = $input.offset();
            var top = offset.top;
            var left = offset.left;

            //set position of the coordinate
            if(align=="left") 
                left -= $caption.outerWidth() + options.marginOfInp;      
            else if(align=="right")
                left += $input.outerWidth() + options.marginOfInp;  
            else if(align=="top")
                top  -= $caption.outerHeight() + options.marginOfInp;
            else if(align=="bottom") 
                top  += $input.outerHeight() + options.marginOfInp;

            if(align=="left" || align=="right"){
                top += ($input.outerHeight()-$caption.outerHeight())/2;  
            }
            else if(align=="top" || align=="bottom"){
                left += ($input.outerWidth()-$caption.outerWidth())/2;
            }    
            // set css and immediately show
            $caption.css({
                top: top,
                left: left
            }).show();
            self.statusShow = true;     
            return this;    
        }
        this.hide = function (){ 
            if(!self.statusShow)
                return this;
            $caption.hide();
            self.statusShow = false;     
            return this; 
        }
        this.remove = function(){
            $bindElements
            .unbind('focus keypress',self.cMouseenter)
            .unbind('blur',self.cMouseleave);
            self.hide();
            $caption.remove();
        }
        this.setOptions(opt).setHTML(html);
        if(options.moreEventZone){
            $bindElements = $bindElements.add(options.moreEventZone);
        }
        $bindElements
        .bind('focus keypress', self.cMouseenter)
        .bind('blur', self.cMouseleave);    
    };
    $.Caption.defaults = {
        align:'right',
        width:220,
        alignsAvailable:{left:true,right:true,top:true,bottom:true},
        marginOfInp:10,
        color:'blue', //Available blue or red
        moreEventZone:{}
    };
})(jQuery);